package top.healthylife.gateway.platform.softwind.dto.basedto.req;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : GaoZeXi
 * @date 2021/7/19 11:35
 */
public class BuildDtoUtil {
    static JSONObject swaggerFactory = new JSONObject();
    //分组信息
    static JSONObject groups = new JSONObject();
    //接口信息
    static List<String> apiUrls = new ArrayList<>();
    //接口地址和出参映射
    static JSONObject mappings = new JSONObject();
    //接口地址和接口名映射
    static JSONObject mappings2 = new JSONObject();
    //定义信息
    static JSONObject definitions = new JSONObject(256);

    static List<TemplateDto> dtos = new ArrayList<>(32);

    static Map<String, String> tagsMappings = new HashMap<>();

    static {
        tagsMappings.put("企业发票", "enterpriseinvoice");
        tagsMappings.put("企业增值税", "enterprisezzs");
        tagsMappings.put("企业所得税", "enterprisesds");
        tagsMappings.put("企业财务报表", "enterprisefinancialreport");
        tagsMappings.put("公司信息", "enterpriseinfo");
        tagsMappings.put("公司其他税务", "enterpriseothertax");

    }

    static String ignoreApi = "";

    static String dtoBaseDir = "com.hare.service.wind.dto";
    static String apiBaseDir = "com.hare.service.api";
    static String className = "WindResDto";
    static String dtoDirectory = "D:\\develop\\IdeaProjects\\hare\\hare\\service-modules\\dynamic-service-interface\\service-dto\\service-softwind-dto\\src\\main\\java\\com\\hare\\service\\wind\\dto\\";
    static String apiDirectory = "D:\\develop\\IdeaProjects\\hare\\hare\\service-modules\\dynamic-service-interface\\service-interface\\interface-softwind-api\\src\\main\\java\\com\\hare\\service\\api\\";
    static String templateTempl = "D:\\develop\\IdeaProjects\\hare\\hare\\service-modules\\dynamic-service-interface\\service-dto\\service-softwind-dto\\src\\main\\java\\com\\hare\\service\\wind\\dto\\basedto\\req\\templateDto.templ";
    static String fieldTempl = "D:\\develop\\IdeaProjects\\hare\\hare\\service-modules\\dynamic-service-interface\\service-dto\\service-softwind-dto\\src\\main\\java\\com\\hare\\service\\wind\\dto\\basedto\\req\\templateField.templ";
    static String apiTempl = "D:\\develop\\IdeaProjects\\hare\\hare\\service-modules\\dynamic-service-interface\\service-dto\\service-softwind-dto\\src\\main\\java\\com\\hare\\service\\wind\\dto\\basedto\\req\\templateApi.templ";

    public static void main(String[] args) {
        parse();
        dtos.forEach(e -> {
            if (e.getFieldDtoList() != null) {
                String dtoDocumentStr = buildDtoDocumentStr(e);
//                String apiDocumentStr = buildApiDocument(e);
                e.setDtoDocument(dtoDocumentStr);
                doBuild(e);
            }

        });
        System.out.println("args = " + args);
    }

    public static void parse() {
        swaggerFactory = JSONUtil.readJSONObject(new File("C:\\Users\\YQ_Gao\\Desktop\\json.txt"), Charset.defaultCharset());
        JSONArray tags = swaggerFactory.getJSONArray("tags");


        tags.stream().map(e -> {
            JSONObject jsonObject = (JSONObject) e;
            return jsonObject.getStr("name");
        });
        JSONObject paths = swaggerFactory.getJSONObject("paths");
        apiUrls = new ArrayList<>(paths.keySet());
        paths.forEach((key, value1) -> {
            //获取出参dto的引用
            TemplateDto templateDto = new TemplateDto();
            JSONObject value = (JSONObject) value1;
            JSONObject get = value.getJSONObject("get");
            if (get == null) {
                get = value.getJSONObject("post");
            }
            JSONObject responses = get.getJSONObject("responses");
            JSONArray tags1 = get.getJSONArray("tags");
            String tag = tags1.stream().map(String::valueOf).collect(Collectors.joining(""));
            String apiName = get.getStr("summary");
            JSONObject jsonObject = responses.getJSONObject("200");
            JSONObject schema = jsonObject.getJSONObject("schema");
            String originalRef = schema.getStr("originalRef");
            mappings.putOpt(key, originalRef);
            mappings2.putOpt(key, apiName);
            String className = key.substring(key.lastIndexOf("/") + 1);
            className = className.substring(0, 1).toUpperCase() + className.substring(1);
            String tempClassName = className;
            tempClassName = tempClassName.replace("Get", "");
            String dtoPackagePath = dtoBaseDir + "." + tagsMappings.get(tag) + ".res";
            String apiPackagePath = apiBaseDir + "." + tagsMappings.get(tag);
            String dtoDirectoryPath = dtoDirectory + tagsMappings.get(tag) + "\\" + "res";
            String apiDirectoryPath = apiDirectory + tagsMappings.get(tag);
            templateDto.setApiName(apiName).setApiUrl(key)
                    .setTag(tag).setResponseRef(originalRef)
                    .setDtoPackagePath(dtoPackagePath).setApiPackagePath(apiPackagePath)
                    .setDtoDirectoryPath(dtoDirectoryPath).setApiDirectoryPath(apiDirectoryPath)
                    .setTempClassName(tempClassName);
            dtos.add(templateDto);
        });
        definitions = swaggerFactory.getJSONObject("definitions");
        dtos.forEach(e -> {
//            if (tagsMappings.containsKey(e.getTag())) {
//                List<FieldDto> fieldDtos = new ArrayList<>();
//                String pageRef = definitions.getJSONObject(e.getResponseRef()).getJSONObject("properties").getJSONObject("data").getStr("originalRef");
//                JSONObject jsonObject = definitions.getJSONObject(pageRef);
//                JSONObject jsonObject1 = jsonObject.getJSONObject("properties").getJSONObject("result");
//                JSONObject jsonObject2 = jsonObject.getJSONObject("properties").getJSONObject("expand");
//
//                String str = jsonObject1.getJSONObject("items").getStr("originalRef");
//                JSONObject jsonObject3 = definitions.getJSONObject(str);
//                JSONObject properties = jsonObject3.getJSONObject("properties");
//                JSONArray required = jsonObject3.getJSONArray("required");
//                String requiredStrs = "";
//                if (required != null) {
//                    requiredStrs = required.stream().map(String::valueOf).collect(Collectors.joining(","));
//                }
//                String requireFinally = requiredStrs;
//                properties.keySet().forEach(k -> {
//                    JSONObject jsonObject4 = properties.getJSONObject(k);
//                    FieldDto fieldDto = new FieldDto();
//                    String type = jsonObject4.getStr("type");
//                    boolean contains = requireFinally.contains(k);
//                    fieldDto.setFieldName(k)
//                            .setValue(jsonObject4.getStr("description"))
//                            .setExample(jsonObject4.getStr("example"))
//                            .setFieldType(type.substring(0, 1).toUpperCase() + type.substring(1))
//                            .setRequired(contains);
//                    fieldDtos.add(fieldDto);
//                });
//
//                FieldDto fieldDto = new FieldDto();
//                fieldDto.setValue(jsonObject2.getStr("description")).setExample("").setFieldName("expand").setFieldType("Object").setRequired(false);
//                fieldDtos.add(fieldDto);
//                e.setFieldDtoList(fieldDtos);
//            }else

            if (e.getTag().equals("纳税基础数据接口")) {

                List<FieldDto> fieldDtos = new ArrayList<>();

                String pageRef = "税务信息汇总详情，如果为null说明没有该数据权限";
                JSONObject jsonObject = definitions.getJSONObject(pageRef);
                JSONObject properties1 = jsonObject.getJSONObject("properties");
                dtos = buildTemplateDtoByJsonObject(properties1);

            }


        });


    }

    @SneakyThrows
    public static String buildDtoDocumentStr(TemplateDto dto) {
        File file = new File(templateTempl);
        String templateDto = IoUtil.read(new FileInputStream(file), Charset.defaultCharset());
        Map<String, Object> variables = BeanUtil.beanToMap(dto);
        variables.put("fields", buildFieldStr(dto.getFieldDtoList()));
        return StrUtil.format(templateDto, variables);
    }

    public static List<TemplateDto> buildTemplateDtoByJsonObject(JSONObject properties1) {
        ArrayList<TemplateDto> templateDtos = new ArrayList<>(properties1.keySet().size());
        TemplateDto templateDto = new TemplateDto();
        String newDtoBaseDir = dtoBaseDir + "." + "taxbasicdata.res";
        String newDtoDirectory = dtoDirectory + "\\taxbasicdata\\res";
        templateDto.setTempClassName("Transaction").setDtoDirectoryPath(newDtoDirectory)
                .setDtoPackagePath(newDtoBaseDir)
                .setApiUrl("/wuneng-web-api/v2/api/fumin/getTransaction")
                .setApiName("纳税基础数据接口-V2.1")
                .setTag("taxbasicdata");
        //处理field
        List<FieldDto> fieldDtos = new ArrayList<>();
        properties1.forEach((k, v) -> {
            String className = handleClassName(k);
            JSONObject jsonObject = properties1.getJSONObject(k);
            String description1 = jsonObject.getStr("description");
            FieldDto fieldDto = new FieldDto();
            fieldDto.setValue(description1)
                    .setRequired(true)
                    .setFieldType(StrUtil.format("List<{}>", className))
                    .setFieldName(k)
                    .setExample("");
            fieldDtos.add(fieldDto);

            //处理子对象
            TemplateDto templateDtoItem = new TemplateDto();
            templateDtoItem.setTempClassName(className).setDtoDirectoryPath(newDtoDirectory)
                    .setDtoPackagePath(newDtoBaseDir)
                    .setApiName(description1)
                    .setTag("taxbasicdata");
            //子对象的field
            String str;
            if (jsonObject.getJSONObject("items") == null) {
                str = jsonObject.getStr("originalRef");
            } else {
                str = jsonObject.getJSONObject("items").getStr("originalRef");
            }
            JSONObject jsonObject1 = definitions.getJSONObject(str);
            JSONObject fieldProperties = jsonObject1.getJSONObject("properties");
            List<FieldDto> fieldItemsList = new ArrayList<>();
            fieldProperties.forEach((fk, fv) -> {
                FieldDto fieldDto1 = new FieldDto();
                JSONObject fieldJson = (JSONObject) fv;
                String type = fieldJson.getStr("type");
                type = type.substring(0, 1).toUpperCase() + type.substring(1);
                fieldDto1.setFieldName(fk).setFieldType(type).setValue(fieldJson.getStr("description")).setExample(fieldJson.getStr("example")==null?"":fieldJson.getStr("example"))
                        .setRequired(true);
                fieldItemsList.add(fieldDto1);
            });
            templateDtoItem.setFieldDtoList(fieldItemsList);
            templateDtos.add(templateDtoItem);
        });
        templateDto.setFieldDtoList(fieldDtos);
        templateDtos.add(templateDto);
        return templateDtos;
    }

    private static String handleClassName(String name) {
        if(name.contains("_")){
            String[] split = name.split("_");
            StringBuilder stringBuilder =new StringBuilder();;
            for (String s : split) {
                String part1 = s.toLowerCase();
                part1 = part1.substring(0, 1).toUpperCase() + part1.substring(1);
                stringBuilder.append(part1);
            }
            return stringBuilder.toString();
        }else{
            name = name.toLowerCase();
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }

    }

    @SneakyThrows
    public static String buildFieldStr(List<FieldDto> list) {
        File file = new File(fieldTempl);
        String templateField = IoUtil.read(new FileInputStream(file), Charset.defaultCharset());
        StringBuilder resultStr = new StringBuilder();
        list.forEach(dto -> {
            Map<String, Object> fieldsMap = BeanUtil.beanToMap(dto);
            String format = StrUtil.format(templateField, fieldsMap);
            resultStr.append(format);
        });
        return resultStr.toString();
    }

    @SneakyThrows
    public static String buildApiDocument(TemplateDto dto) {
        File file = new File(apiTempl);
        String api = IoUtil.read(new FileInputStream(file), Charset.defaultCharset());
        Map<String, Object> variables = BeanUtil.beanToMap(dto);
        return StrUtil.format(api, variables);
    }


    @SneakyThrows
    public static void doBuild(TemplateDto dto) {
        //创建dto
        File targetDir = new File(dto.getDtoDirectoryPath());
        if (!targetDir.exists()) {
            targetDir.mkdir();
        }
        String tempClassName = dto.getTempClassName();
//        String dtoClassName = "WindRes" + tempClassName + "Dto";
        String dtoClassName = tempClassName;
        File file = new File(targetDir + "\\" + dtoClassName + ".java");
        IoUtil.write(new FileOutputStream(file), false, dto.getDtoDocument().getBytes());
        System.out.println(dtoClassName + "生成完毕");
        //创建Api
        if (dto.getApiDocument() != null) {
            File targetDir2 = new File(dto.getApiDirectoryPath());
            if (!targetDir2.exists()) {
                targetDir2.mkdir();
            }
            String apiClassName = "Wind" + tempClassName + "Api";
            File api = new File(targetDir2 + "\\" + apiClassName + ".java");
            IoUtil.write(new FileOutputStream(api), false, dto.getApiDocument().getBytes());
            System.out.println(apiClassName + "生成完毕");
        }

    }


}
